package com.stars.easyms.datasource.transaction;

import com.stars.easyms.datasource.EasyMsDataSource;
import com.stars.easyms.datasource.EasyMsMasterSlaveDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.transaction.support.TransactionSynchronizationManager;

/**
 * <p>className: EasyMsTransactionSynchronizationManager</p>
 * <p>description: EasyMs事务同步管理类</p>
 *
 * @author guoguifang
 * @date 2019-11-30 23:17
 * @since 1.4.2
 */
@Slf4j
public final class EasyMsTransactionSynchronizationManager {

    private static final ThreadLocal<EasyMsTransactionManager> TRANSACTION_MANAGER_HOLDER = new NamedThreadLocal<>("Current easy-ms aspect-driven transaction");

    static void setTransactionManager(@NonNull EasyMsTransactionManager easyMsTransactionManager) {
        TRANSACTION_MANAGER_HOLDER.set(easyMsTransactionManager);
        if (!TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.initSynchronization();
        }
    }

    public static boolean isSynchronizationActive() {
        EasyMsTransactionManager easyMsTransactionManager = TRANSACTION_MANAGER_HOLDER.get();
        return easyMsTransactionManager != null && easyMsTransactionManager.hasTransactionStatus();
    }

    public static boolean isActualTransactionActive() {
        EasyMsTransactionManager easyMsTransactionManager = TRANSACTION_MANAGER_HOLDER.get();
        return easyMsTransactionManager != null && easyMsTransactionManager.isActualTransactionActive();
    }

    @NonNull
    public static EasyMsDataSource getFixedMasterEasyMsDataSource(@NonNull EasyMsMasterSlaveDataSource easyMsMasterSlaveDataSource) {
        return TRANSACTION_MANAGER_HOLDER.get().getFixedMasterEasyMsDataSource(easyMsMasterSlaveDataSource);
    }

    @Nullable
    public static String getCurrentTransactionName() {
        EasyMsTransactionManager easyMsTransactionManager = TRANSACTION_MANAGER_HOLDER.get();
        return easyMsTransactionManager != null ? easyMsTransactionManager.getCurrentTransactionName() : null;
    }

    public static boolean isCurrentTransactionReadOnly() {
        EasyMsTransactionManager easyMsTransactionManager = TRANSACTION_MANAGER_HOLDER.get();
        return easyMsTransactionManager != null && easyMsTransactionManager.isCurrentTransactionReadOnly();
    }

    @Nullable
    public static Integer getCurrentTransactionIsolationLevel() {
        EasyMsTransactionManager easyMsTransactionManager = TRANSACTION_MANAGER_HOLDER.get();
        return easyMsTransactionManager != null ? easyMsTransactionManager.getCurrentTransactionIsolationLevel() : null;
    }

    @NonNull
    public static EasyMsTransactionStatusHolder newTransactionStatusHolder(@NonNull EasyMsDataSource easyMsDataSource) {
        return TRANSACTION_MANAGER_HOLDER.get().newTransactionStatusHolder(easyMsDataSource);
    }

    @Nullable
    static EasyMsTransactionManager getTransactionManager() {
        return TRANSACTION_MANAGER_HOLDER.get();
    }

    static void clearTransactionManager() {
        TRANSACTION_MANAGER_HOLDER.remove();
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.clearSynchronization();
        }
    }

    private EasyMsTransactionSynchronizationManager() {
    }
}